Passed
Push — dev ( c5bc2a...3c211c )
by Kasper
01:09 queued 12s
created

Map.tsx ➔ Map   D

Complexity

Conditions 9

Size

Total Lines 216
Code Lines 148

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 148
dl 0
loc 216
rs 4.6666
c 0
b 0
f 0
cc 9

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
import { useState, useEffect, useRef } from 'react';
2
import { ScrollView, Image, Text, View, StyleSheet, StatusBar, Button, Pressable, InteractionManagerStatic, TouchableHighlightBase } from 'react-native';
3
import MapView, { Marker, Circle, Polygon } from 'react-native-maps';
4
import * as Location from 'expo-location';
5
import React from 'react';
6
import mapModel from '../models/map';
7
import scooterModel from '../models/scooter';
8
import Icon from 'react-native-vector-icons/Octicons';
9
import ScooterModal from './modals/ScooterModal';
10
import NavBar from './drawer/NavBar';
11
import ZoneModal from './modals/ZoneModal';
12
import { showMessage, hideMessage } from "react-native-flash-message";
13
import QrScanner from './modals/QrScanner';
14
import JourneyModal from './modals/JourneyModal';
15
16
const marker = require('../assets/scooter_white.png');
17
const selectedMarker = require('../assets/scooter_blue.png');
18
19
function markerIcon(index, selected) {
20
    if (index === selected) {
21
        return selectedMarker;
22
    }
23
    return marker;
24
};
25
26
export default function Map({navigation, API_KEY, position, setPosition, token}): any {
27
    const [locationMarker, setLocationMarker] = useState(null);
28
    const [currentCity, setCurrentCity] = useState(null);
29
    const [zones, setZones] = useState([]);
30
    const [scooters, setScooters] = useState([]);
31
    const [currentScooter, setCurrentScooter] = useState(null);
32
    const [modalVisible, setModalVisible] = useState(false);
33
    const [zoneModalVisible, setZoneModalVisible] = useState(false);
34
    const [currentZone, setCurrentZone] = useState(null);
35
    const [cameraVisible, setCameraVisible] = useState(false);
36
    const [journeyModal, setJourneyModal] = useState(false);
37
    const [toggleTimer, setToggleTimer] = useState(false);
38
    const [markerSelected, setMarkerSelected] = useState(null);
39
    
40
    const mapRef = useRef(null);    
41
    /**
42
     * Set user position
43
     */
44
    useEffect(() => {
45
        async function setUpMap(): Promise<void> {
46
            const { status } = await Location.requestForegroundPermissionsAsync();
47
48
            if (status !== 'granted') {
49
                showMessage({
50
                    message: 'Permission to access location was denied',
51
                    type: 'danger',
52
                    position: 'center'
53
                });
54
                return;
55
            }
56
57
            const currentLocation = await Location.getCurrentPositionAsync({});
58
59
            const userCoordinates = {
60
                //latlang hardcoded for testing
61
                latitude: await currentLocation.coords.latitude,
62
                longitude: await currentLocation.coords.longitude
63
                // latitude: 56.674283063446495,
64
                // longitude: 12.857826360096537
65
            };
66
67
            
68
            
69
            setPosition(userCoordinates);
70
            
71
            // mapModel.getClosestCity(position);
72
73
            setLocationMarker(<Marker
74
                coordinate={{
75
                    //latlang hardcoded for testing
76
                    latitude: currentLocation.coords.latitude,
77
                    longitude: currentLocation.coords.longitude
78
                    // latitude: 56.161013580817986,
79
                    // longitude: 15.587742977884904
80
                }}
81
                title="My location"
82
                pinColor="blue"
83
                flat={false}
84
            />);
85
86
87
            // Get closest city to user location
88
            const city = await mapModel.getClosestCity(userCoordinates);
89
            
90
            
91
            // Set city that is closest to user
92
            setCurrentCity(city);
93
            
94
            
95
            /**
96
             * Set zones on map
97
             */
98
            const zones = mapModel.getZones(city);
99
            setZones(zones);
100
        };
101
102
103
        setUpMap();
104
105
    }, []);
106
107
    /**
108
     * Get scooters for current city,
109
     * Updated every 5 seconds
110
     */
111
    useEffect(() => {
112
        const interval = setInterval(() => {
113
114
            // Get scooters
115
            async function getScooters() {
116
                // const city = await mapModel.getClosestCity(position);
117
                
118
                const result = await scooterModel.getScooters(currentCity); 
119
                
120
                if (result) {
121
                    const scooters = result['cityScooters'];
122
                    
123
                    const sortedScooters = scooterModel.sortAvailableScooters(scooters);
124
                    setScooters(sortedScooters);
125
                };
126
127
            };
128
129
      
130
            getScooters();
131
132
        }, 2000);
133
        return () => clearInterval(interval);
134
      });
135
    
136
    /**
137
     * Update user position
138
     */
139
    useEffect(() => {
140
        const interval = setInterval(() => {
141
142
            // Get scooters
143
            async function updateUserPosition() {
144
                const currentLocation = await Location.getCurrentPositionAsync({});
145
                const userCoordinates = {
146
                    //latlang hardcoded for testing
147
                    latitude: await currentLocation.coords.latitude,
148
                    longitude: await currentLocation.coords.longitude
149
                    // latitude: 56.674283063446495,
150
                    // longitude: 12.857826360096537
151
                };
152
                
153
                setPosition(userCoordinates);
154
            };
155
156
            updateUserPosition();
157
158
        }, 2000);
159
        return () => clearInterval(interval);
160
      });
161
162
163
164
    return (
165
        <View style={styles.container}>
166
            
167
            {journeyModal ?
168
                <View
169
                style={{
170
                    width: '100%',
171
                    height: 50,
172
                    backgroundColor: 'white',
173
                    zIndex: 1
174
                }}
175
                />
176
                    :
177
                <View></View>
178
            }
179
180
            <MapView
181
                ref={mapRef}
182
                style={styles.map}
183
                initialRegion={{
184
                    latitude: position.latitude? position.latitude : 56.161013580817986,
185
                    longitude: position.longitude? position.longitude : 15.587742977884904,
186
                    latitudeDelta: 0.03,
187
                    longitudeDelta: 0.03,
188
                }}
189
            >
190
                {locationMarker}
191
192
                {scooters.map((s, index) => 
193
                    <Marker
194
                        coordinate={s['coordinates']}
195
                        icon={markerIcon(index, markerSelected)}
196
                        tappable={true}
197
                        key={index}
198
                        onPress={() => {
199
                            setCurrentScooter(s);                                                        
200
                            setModalVisible(true);
201
                            setMarkerSelected(index);                            
202
                        }}
203
                        >
204
                    </Marker>
205
                )}
206
                {zones.map((z, index) => (                    
207
                    <Polygon 
208
                        coordinates={z['coordinates']}
209
                        strokeColor={z['zoneColor']}
210
                        strokeWidth={3}
211
                        fillColor={z['zoneColor']}
212
                        key={index}
213
                        tappable={true}
214
                        onPress={() => {
215
                            setCurrentZone(z)
216
                            setZoneModalVisible(true)                            
217
                        }}
218
                    />
219
                ))}
220
            </MapView>
221
222
            <ScooterModal navigation={navigation} scooter={currentScooter} modalVisible={modalVisible} currentCity={currentCity} setModalVisible={setModalVisible} setJourneyModal={setJourneyModal} setToggleTimer={setToggleTimer} position={position} setCurrentScooter={setCurrentScooter}/> 
223
224
            <ZoneModal navigation={navigation} zone={currentZone} zoneModalVisible={zoneModalVisible} setZoneModalVisible={setZoneModalVisible} currentCity={currentCity}/>
225
            
226
 
227
            <JourneyModal navigation={navigation} scooter={currentScooter} journeyModal={journeyModal} setJourneyModal={setJourneyModal} toggleTimer={toggleTimer} setToggleTimer={setToggleTimer}/>
228
229
            <Pressable onPress={() => {setCameraVisible(true)}} style={styles.googleLogin}>
230
                    <Icon 
231
                        name='screen-full' 
232
                        size={15} 
233
                        color='white'
234
                    />
235
                    <Text style={styles.googleText}>Scan to unlock</Text>
236
            </Pressable>
237
            
238
            <NavBar navigation={navigation} mapRef={mapRef} position={position}/>
239
            <QrScanner navigation={navigation} cameraVisible={cameraVisible} setCameraVisible={setCameraVisible} scooter={currentScooter} setModalVisible={setModalVisible} currentCity={currentCity} setCurrentScooter={setCurrentScooter}/>
240
        </View>
241
        
242
    )
243
}
244
245
const styles = StyleSheet.create({
246
    container: {
247
        height: '100%',
248
        alignItems: "center",
249
        width: '100%'
250
    },
251
252
    map: {
253
        position: 'absolute',
254
        top: 0,
255
        left: 0,
256
        bottom: 0,
257
        right: 0,
258
    },
259
260
    drawer: {
261
        position: 'absolute',
262
        width: 50,
263
        height: 50, 
264
        left: 50,
265
        backgroundColor: 'white',
266
        marginTop: 50,
267
        borderRadius: 25,
268
        justifyContent: 'center',
269
        alignItems: 'center'
270
    },
271
    
272
    shadowProp: {
273
        elevation: 5,
274
        shadowColor: 'black'
275
    },
276
277
    googleLogin: {
278
        backgroundColor: '#1A1A1A',
279
        width: '65%',
280
        height: 45,
281
        borderRadius: 25,
282
        display: 'flex',
283
        flexDirection: 'row',
284
        justifyContent: 'center',
285
        alignItems: 'center',
286
        marginBottom: 30
287
    },
288
289
    googleText: {
290
        color: 'white',
291
        fontWeight: 'bold',
292
        fontSize: 18,
293
        marginLeft: 10
294
    },
295
296
    googleIcon: {
297
        height: 20,
298
        width: 20
299
    }
300
});
301
302